#pragma  once
#include <queue>
#include <mutex>
#include <condition_variable>
namespace Media {
    template<typename T>
    class ThreadSafeQueue {
    private:
        std::queue<T> queue_;
        mutable std::mutex mutex_;
        std::condition_variable cond_;
        T lastData_;
        bool dataGo = false;
    public:
        bool Push(const T &value) {
            std::unique_lock<std::mutex> lock(mutex_);
            if(queue_.size() > 10){
                queue_.front();
            }
            queue_.push(value);
            lastData_ = value;
            if(!dataGo){
                dataGo = true;
            }
            lock.unlock();
            cond_.notify_one();
            return true;
        }

        bool Pop(T& item, std::chrono::milliseconds timeout = std::chrono::milliseconds(3)) {
            std::unique_lock<std::mutex> lock(mutex_);
            if (cond_.wait_for(lock, timeout, [this] { return !queue_.empty(); })) {
                item = queue_.front();
                queue_.pop();
                return true;
            } else {
                if(dataGo) {
                    item = lastData_;
                    return true;
                }
            }
            return false;
        }

        size_t Size() const {
            std::unique_lock<std::mutex> lock(mutex_);
            return queue_.size();
        }

        bool Empty() const {
            std::unique_lock<std::mutex> lock(mutex_);
            return queue_.empty();
        }
    };
}